#ifndef __DETECTOR_
#define __DETECTOR_

#include <opencv2/opencv.hpp>
#include <inference_engine.hpp>
#include <memory.h>
#include <string.h>

using namespace InferenceEngine;

class Detector;
using p_detector = std::shared_ptr<Detector>;

typedef struct
{
    // 置信度
    float prob;
    // 标签
    std::string target;
    // Bounding Box
    cv::Rect2f rect;
    // 中心
    cv::Point2f center;
    // 深度
    uint16_t depth;
} Object;

/**
 * @brief  激活函数
 * @param  x 输入
 * @return float  激活后输出
 */
inline float sigmoid(float x)
{
    return (1 / (1 + exp(-x)));
}

class Detector
{
public:
    Detector(const std::string &);
    ~Detector(){};

    // 推论
    std::vector<Object> inference(const cv::Mat &, const cv::Size &, cv::Mat &);
    // 绘制Bounding Box
    void drawBox(cv::Mat &);

private:
    // 预处理
    void _preProcess(const cv::Mat &, const cv::Size &);
    // 后处理
    std::vector<Object> _postProcess();

    // 获取Anchors
    std::vector<int> _getAnchors(const int &);
    // 分层处理
    void _boxProcess(const Blob::Ptr &, const int &);
    // Bounding Box映射
    cv::Rect _boxMapping(const cv::Rect&);

private:
    //存储初始化获得的可执行网络
    ExecutableNetwork _network;
    OutputsDataMap _outputInfo;
    InferRequest::Ptr _inferRequest;

    // 原始rgb图像
    cv::Mat _frame;
    // 深度图像
    cv::Mat _depth;
    // 随机颜色生成容器
    std::vector<cv::Scalar> _colors;

    // 处理过的rgb图像
    cv::Mat _copeFrame;

    // 置信度阈值
    float _confThres;
    // 非极大值抑制阈值
    float _nmsThres;
    // 输入层名称
    std::string _inputName;
    // 检测物体的种类数量
    size_t _itemSize;
    // Bounding Box
    std::vector<cv::Rect> _originRect;
    // Bounding Box置信度
    std::vector<float> _originRectConf;
    // Bounding Box标签
    std::vector<std::string> _originTarget;
    //检测到的物体
    std::vector<Object> _objects;
};

std::vector<cv::Scalar> randColor(const size_t &);

#endif